package com.qq.BFMRSE.index;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import net.sf.json.JSONObject;
import com.qq.BFMRSE.entity.encryptedIndex;
import com.qq.BFMRSE.entity.indexTree;
import com.qq.BFMRSE.entity.indexTreeNode;
import com.qq.BFMRSE.indexTree.buildIndexTreeHelper;
import com.qq.BFMRSE.serialize.objectSerializeUtil;
import com.qq.BFMRSE.util.BFConstants;
public class buildIndex {
	private indexEncrypted inSk;
	private String skFile;
	private transient Integer docNum;
	private transient Integer dealedNum;//忽略这两个属性不行序列化
	public indexEncrypted getInSk() {
		return inSk;
	}
	public void setInSk(indexEncrypted inSk) {
		this.inSk = inSk;
	}
	public String getSkFile() {
		return skFile;
	}
	public void setSkFile(String skFile) {
		this.skFile = skFile;
	}
	public Integer getDocNum() {
		return docNum;
	}
	public void setDocNum(Integer docNum) {
		this.docNum = docNum;
	}
	public Integer getDealedNum() {
		return dealedNum;
	}
	public void setDealedNum(Integer dealedNum) {
		this.dealedNum = dealedNum;
	}
	public buildIndex(indexEncrypted inSk,String skFile,Integer docNum,Integer dealedNum){
		this.inSk=inSk;
		this.skFile=skFile;
		this.docNum=docNum;
		this.dealedNum=dealedNum;
	}
	public buildIndex(String skFile){
		System.out.println("test buildIndex start");
		this.skFile=skFile;
		inSk=getEncryptedSK();
		docNum=0;
		dealedNum=0;
		
	}
	public buildIndex(indexEncrypted inSk,String skFile){
		this.inSk=inSk;
		this.skFile=skFile;
	}
	/**
	 * 建立明文索引树,并将其序列化到luIndex文件夹下
	 * @return
	 */
	public indexTree buildIndexTree(List<String> fileNameList){
		indexTree searchIndexTree=new indexTree();
		Queue<indexTreeNode> queue=buildIndexTreeHelper.getallLeafIndexTree(fileNameList);
		searchIndexTree.buildBalanceBinTree(queue);
		String indexTreePath=BFConstants.INDEXPATH+File.separator+BFConstants.ROOT;
		try {
			objectSerializeUtil.serialize(searchIndexTree.getRoot(), indexTreePath);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return searchIndexTree;
	}
	
	/**
	 * 得到fileNameList内所有文件的加密的索引
	 * @param fileNameList
	 * @return
	 */
	public Map<String, encryptedIndex> getAllEncryptedIndexs(List<String> fileNameList)
	{
		Map<String, encryptedIndex>indexMap=new HashMap<String, encryptedIndex>();
		Iterator<String>iterator=fileNameList.iterator();
		encryptedIndex tempEnIndex=new encryptedIndex();
		docNum=fileNameList.size();
		dealedNum=0;
		while(iterator.hasNext())
		{
			String fileName=iterator.next();
			double []plainIndex=indexHelper.getSearchPlainIndex(fileName);
			tempEnIndex=inSk.IndexEncrypted(plainIndex);
			indexMap.put(fileName, tempEnIndex);
			dealedNum++;
			//resultList.add(getNewEncryptedIndex(fileName));
		}
		return indexMap;
	}
	/**
	 * 得到文件fileName的加密的索引
	 * @param fileName
	 * @return
	 */
	public  encryptedIndex getNewEncryptedIndex(String fileName)
	{
		encryptedIndex resultEnIndex=new encryptedIndex();
		double []plainIndex=indexHelper.getSearchPlainIndex(fileName);
		if(inSk==null){
			inSk=getEncryptedSK();
		}
		resultEnIndex=inSk.IndexEncrypted(plainIndex);
		return resultEnIndex;
	}
	public  encryptedIndex getNewEncryptedIndex(String fileName,indexEncrypted inSK)
	{
		encryptedIndex resultEnIndex=new encryptedIndex();
		double []plainIndex=indexHelper.getSearchPlainIndex(fileName);
		resultEnIndex=inSK.IndexEncrypted(plainIndex);
		return resultEnIndex;
	}
	/**
	 * 得到fileNameList内所有文件的加密的索引的json串信息
	 * @param 
	 * @return
	 */
	public String getEncryptedIndexJsonInfo(List<String> fileNameList)
	{
		//List<String> fileNameList=luceneOperation.getAllFileName("D:\\testIndex");
		Map<String, encryptedIndex>indexMap=getAllEncryptedIndexs(fileNameList);
		if(indexMap.size()==0)
		{
			return null;
		}
		else {
			JSONObject jObject=JSONObject.fromObject(indexMap);
			return jObject.toString();
		}
	}

	/**
	 * 得到一个秘钥三元组，如果已经为该数据拥有者生成了SK，那么直接从文件中读取，否者为
	 * 新的数据拥有者生成一个新的SK.
	 * @return
	 */
	public indexEncrypted getEncryptedSK()
	{
		String relskFile=skFile+File.separator+BFConstants.SK;
		System.out.println("test relskFile:"+relskFile);
		System.out.println("test skFile:"+skFile);
		indexEncrypted resultSK=null;
		File file=new File(relskFile);
		if(file.exists()&&file.length()!=0)
		{
			try {
				resultSK=(indexEncrypted) objectSerializeUtil.deserialize(relskFile);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else {
			System.out.println("test getEncryptedSK start");
			resultSK=new indexEncrypted();
			try {
				objectSerializeUtil.serialize(resultSK, relskFile);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return resultSK;
	}
	/**
	 * 添加文件时，得到新添加文件的加密索引
	 * @param fileName
	 * @return
	 */
	public  encryptedIndex getaddFileEncryptedIndex(String fileName)
	{
		encryptedIndex resultEnIndex=null;
		double []plainIndex=indexHelper.getSearchPlainIndex(fileName);
		if(inSk==null){
			inSk=readEncryptedSK();
		}
		if(inSk!=null){
			resultEnIndex=inSk.IndexEncrypted(plainIndex);
		}
		return resultEnIndex;
	}
	/**
	 * 仅仅从文件中读取秘钥
	 * @return
	 */
	public indexEncrypted readEncryptedSK()
	{
		String relskFile=skFile+File.separator+BFConstants.SK;
		System.out.println("test relskFile:"+relskFile);
		System.out.println("test skFile:"+skFile);
		indexEncrypted resultSK=null;
		File file=new File(relskFile);
		if(file.exists()&&file.length()!=0)
		{
			try {
				resultSK=(indexEncrypted) objectSerializeUtil.deserialize(relskFile);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return resultSK;
	}
	/**
	 * 扩展秘钥
	 * @param extSize
	 */
	public void extendSK(int extSize){
		inSk.genExtSK(extSize);
		String relskFile=skFile+File.separator+BFConstants.SK;
		try {
			objectSerializeUtil.serialize(inSk, relskFile);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}